﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using RuoVea.ExConfig;
using RuoVea.ExUtil;
using RuoVea.Identity.Utils;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

using Microsoft.AspNetCore.Mvc.Filters;
 
using System.Web;

namespace RuoVea.Identity.Client;

/// <summary>
/// 校验是否登录引用
/// </summary>
public class AuthorizeAttribute : Attribute, IAuthorizationFilter
{
    public int Order { get; set; } = 0;
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        AuthClientInfo authClientInfo = ClientConfig.authClientInfo;
        var data = context.HttpContext.User.Identity;
        if (data != null && data.IsAuthenticated == false)
        {
            var cookies = context.HttpContext.Request?.Cookies?.Where(x => x.Key == "Cookies" || x.Key == "token").Select(x => x.Value).FirstOrDefault();
            if (cookies.IsNullOrWhiteSpace())
            {
                var authority = authClientInfo.ServerUrl;
                string clientId = authClientInfo.ClientId;
                string redirectUris = authClientInfo.RedirectUris;
                string responseType = authClientInfo.ResponseType.ToString();
                var hostUrl = authClientInfo.HostUri;

                string enrNonce = ConfigUtil.EnrNonce(authClientInfo.ClientId, authClientInfo.ClientSecrets, authClientInfo.HostUri + authClientInfo.RedirectUris, authClientInfo.ResponseType.ToString());

                string state = authClientInfo.state;
                string returnUrl = authClientInfo.HostUri + context.HttpContext.Request.Path;
                returnUrl = HttpUtility.UrlEncode(returnUrl);
                string uri = $"{authority}/auth/myauthorize?clientid={clientId}&redirecturi={HttpUtility.UrlEncode(hostUrl + redirectUris)}&responsetype={responseType}&state={state}&nonce={enrNonce}&returnurl={returnUrl}";
                context.HttpContext.Response.Redirect(uri);
            }
            else
            {
                if (context.HttpContext.User.Claims.Count() == 0)
                {
                    var jwtHandler = new JwtSecurityTokenHandler();
                    JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(cookies);

                    var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                    identity.AddClaims(jwtToken.Claims);
                    ClaimsPrincipal claims = new ClaimsPrincipal(identity) { };
                    context.HttpContext.User = claims;
                    context.HttpContext.SignInAsync(identity.AuthenticationType, claims, new AuthenticationProperties { ExpiresUtc = new System.DateTimeOffset(dateTime: DateTime.Now.AddMinutes(1440)) });
                    context.HttpContext.Response.Cookies.Append("Cookies", cookies);
                }
            }
        }
    }
}